﻿package com.sh.game.loader
{
    import com.sh.game.consts.*;
    import com.sh.game.global.*;
    import com.sh.game.util.*;
    import flash.net.*;
    import flash.utils.*;
    import morn.core.handlers.*;

    public class SWFActionLoader2 extends Object implements IDestroy
    {
        private var MAX_CACHE:int = 0;
        private var MIN_CACHE:int = 0;
        private var _nameToSource:Dictionary;
        private var _loadings:Dictionary;
        private var _dataUrls:Array;
        private var _dataDic:Dictionary;
        private var _comFuncsByName:Dictionary;
        private var _cacheList:Array;
        private var _cacheAssetsCount:int = 0;
        private var _inuseDic:Dictionary;
        private var _urlLoader:URLLoader;
        private var _loaderIDs:Dictionary;
        private var _curFile:int = 0;
        private var _isLoading:Boolean = false;
        private static var _instance:SWFActionLoader2 = null;

        public function SWFActionLoader2()
        {
            this._nameToSource = new Dictionary();
            this._loadings = new Dictionary();
            this._dataUrls = [];
            this._dataDic = new Dictionary();
            this._comFuncsByName = new Dictionary();
            this._cacheList = new Array();
            this._inuseDic = new Dictionary();
            this._loaderIDs = new Dictionary();
            return;
        }// end function

        public function initByConfig(param1:int = 120, param2:int = 50) : void
        {
            this.MAX_CACHE = param1;
            this.MIN_CACHE = param2;
            return;
        }// end function

        public function load(param1:String, param2:Function, param3:String, param4:int, param5:Boolean = true, param6:int = -1, param7:int = 0, param8:int = 0) : void
        {
            var _loc_9:* = ModelName.getSource(param3, param4, param6);
            this.loadSource(param1, _loc_9, param2, param6, param5, param7, param8);
            return;
        }// end function

        private function loadSource(param1:String, param2:int, param3:Function, param4:int, param5:Boolean = true, param6:int = 1, param7:int = 0) : void
        {
            if (param2 == 0)
            {
                return;
            }
            if (param5)
            {
                if (param7 > 0 && this._loaderIDs[param7] && this._loaderIDs[param7][param2])
                {
                }
                else
                {
                    if (param7 > 0)
                    {
                        if (!this._loaderIDs[param7])
                        {
                            this._loaderIDs[param7] = new Object();
                        }
                        this._loaderIDs[param7][param2] = true;
                    }
                    if (this._inuseDic.hasOwnProperty(param2))
                    {
                        var _loc_8:* = this._inuseDic;
                        var _loc_9:* = param2;
                        var _loc_10:* = this._inuseDic[param2] + 1;
                        _loc_8[_loc_9] = _loc_10;
                    }
                    else
                    {
                        this._inuseDic[param2] = 1;
                    }
                }
            }
            if (this._nameToSource[param2])
            {
                if (param3 != null)
                {
                    this.param3(this._nameToSource[param2], param2, param4);
                }
                return;
            }
            if (!this._comFuncsByName[param2])
            {
                this._comFuncsByName[param2] = new Array();
            }
            this._comFuncsByName[param2].push(param3);
            if (this._loadings[param2] || this._dataDic[param2])
            {
                return;
            }
            param6 = param6 < 9 ? (9) : (10);
            this._dataUrls.push(param2);
            this._dataDic[param2] = {prority:param6, dic:param1, dir:param4};
            if (this._isLoading == false)
            {
                this.loadNextData();
            }
            return;
        }// end function

        private function loadNextData() : void
        {
            var _loc_1:Object = null;
            var _loc_2:int = 0;
            var _loc_3:int = 0;
            var _loc_4:String = null;
            if (this._dataUrls && this._dataUrls.length > 0)
            {
                this._curFile = this._dataUrls.shift();
                _loc_1 = this._dataDic[this._curFile];
                this._dataDic[this._curFile] = null;
                delete this._dataDic[this._curFile];
                if (_loc_1 == null || this._inuseDic[this._curFile] <= 0)
                {
                    this.loadNextData();
                    return;
                }
                this._isLoading = true;
                _loc_2 = this._curFile;
                _loc_3 = _loc_1.prority;
                _loc_4 = this.doLoad(this._curFile, _loc_1.dic + _loc_2 + ".dat", _loc_3, _loc_1.dir, true);
                this._loadings[this._curFile] = _loc_4;
            }
            else
            {
                this._isLoading = false;
            }
            return;
        }// end function

        private function onCompleteFunc(param1:int, param2:int = -1, param3:Boolean = false, param4 = null) : void
        {
            var _loc_5:Function = null;
            if (!(param1 in this._nameToSource))
            {
                this._cacheList.push(param1);
            }
            this._nameToSource[param1] = param4;
            this._loadings[param1] = null;
            delete this._loadings[param1];
            var _loc_6:String = this;
            var _loc_7:* = this._cacheAssetsCount + 1;
            _loc_6._cacheAssetsCount = _loc_7;
            if (this._comFuncsByName[param1] && this._comFuncsByName[param1].length > 0)
            {
                for each (_loc_5 in this._comFuncsByName[param1])
                {
                    
                    if (_loc_5 != null)
                    {
                        this._loc_5(param4, param1, param2);
                    }
                }
                this._comFuncsByName[param1] = null;
                delete this._comFuncsByName[param1];
            }
            if (param3)
            {
                this._isLoading = false;
                this.loadNextData();
            }
            return;
        }// end function

        private function doLoad(param1:int, param2:String, param3:int, param4:int, param5:Boolean = false) : String
        {
            param2 = Config.getUrl(param2, ResourceType.NORMAL);
            App.mloader3.loadBYTE(param2, param3, new Handler(this.readAction, [param1, param4, param5]), null, null, false);
            return param2;
        }// end function

        private function readAction(param1:int, param2:int, param3:Boolean, param4) : void
        {
            var _loc_5:* = new ActionAssets(param4 as ByteArray, param1 + "", this.onCompleteFunc, [param1, param2, param3]);
            new ActionAssets(param4 as ByteArray, param1 + "", this.onCompleteFunc, [param1, param2, param3]).read();
            return;
        }// end function

        private function checkCache() : void
        {
            var _loc_2:int = 0;
            var _loc_1:int = 0;
            if (this._cacheList.length > this.MAX_CACHE)
            {
                _loc_1 = this._cacheList.length - this.MAX_CACHE;
            }
            var _loc_3:int = 0;
            var _loc_4:int = 0;
            var _loc_5:* = this._cacheList.length;
            while (_loc_1 > 0 && _loc_3 < _loc_5)
            {
                
                _loc_2 = this._cacheList[_loc_4];
                if (this._inuseDic[_loc_2] == 0)
                {
                    this._nameToSource[_loc_2].dispose();
                    this._nameToSource[_loc_2] = null;
                    delete this._nameToSource[_loc_2];
                    this._cacheList.splice(_loc_4, 1);
                    _loc_1 = _loc_1 - 1;
                }
                else
                {
                    _loc_4++;
                }
                _loc_3++;
            }
            if (this._cacheList.length > this.MIN_CACHE)
            {
                _loc_1 = this._cacheList.length - this.MIN_CACHE;
            }
            _loc_3 = 0;
            _loc_4 = 0;
            _loc_5 = this._cacheList.length;
            var _loc_6:* = getTimer();
            while (_loc_1 > 0 && _loc_3 < _loc_5)
            {
                
                _loc_2 = this._cacheList[_loc_4];
                if (this._inuseDic[_loc_2] == 0)
                {
                    this._nameToSource[_loc_2].dispose();
                    this._nameToSource[_loc_2] = null;
                    delete this._nameToSource[_loc_2];
                    this._cacheList.splice(_loc_4, 1);
                    _loc_1 = _loc_1 - 1;
                }
                else
                {
                    _loc_4++;
                }
                _loc_3++;
            }
            return;
        }// end function

        public function clearCaches() : void
        {
            var _loc_6:String = null;
            var _loc_7:int = 0;
            var _loc_8:int = 0;
            var _loc_1:int = 0;
            var _loc_2:Boolean = false;
            _loc_1 = this._cacheList.length;
            var _loc_3:int = 0;
            var _loc_4:int = 0;
            var _loc_5:* = this._cacheList.length;
            while (_loc_1 > 0 && _loc_3 < _loc_5)
            {
                
                _loc_7 = this._cacheList[_loc_4];
                if (this._inuseDic[_loc_7] == 0)
                {
                    if (this._loadings[_loc_7])
                    {
                        if (this._curFile == _loc_7 && this._isLoading)
                        {
                            this._curFile = 0;
                            this._isLoading = false;
                            _loc_2 = true;
                        }
                        delete this._loadings[_loc_7];
                    }
                    this._nameToSource[_loc_7].dispose();
                    this._nameToSource[_loc_7] = null;
                    delete this._inuseDic[_loc_7];
                    delete this._nameToSource[_loc_7];
                    this._cacheList.splice(_loc_4, 1);
                    _loc_1 = _loc_1 - 1;
                }
                else
                {
                    _loc_4++;
                }
                _loc_3++;
            }
            for (_loc_6 in this._dataDic)
            {
                
                if (!this._inuseDic[_loc_6] || this._inuseDic[_loc_6] == 0)
                {
                    delete this._inuseDic[_loc_7];
                    _loc_8 = this._dataUrls.indexOf(_loc_6);
                    if (_loc_8 > -1)
                    {
                        this._dataUrls.splice(_loc_8, 1);
                    }
                    this._dataDic[_loc_6] = null;
                    delete this._dataDic[_loc_6];
                }
            }
            if (_loc_2)
            {
                this.loadNextData();
            }
            return;
        }// end function

        public function destroyRes(param1:int) : void
        {
            var _loc_2:Boolean = false;
            if (this._nameToSource[param1])
            {
                if (this._loadings[param1])
                {
                    if (this._curFile == param1 && this._isLoading)
                    {
                        this._isLoading = false;
                        this._curFile = 0;
                        _loc_2 = true;
                    }
                    delete this._loadings[param1];
                }
                this._nameToSource[param1].dispose();
                this._nameToSource[param1] = null;
                delete this._inuseDic[param1];
                delete this._nameToSource[param1];
                this._cacheList.splice(this._cacheList.indexOf(param1), 1);
            }
            if (_loc_2)
            {
                this.loadNextData();
            }
            return;
        }// end function

        public function unload(param1:int, param2:Boolean = false, param3:int = 0) : void
        {
            var _loc_5:int = 0;
            var _loc_4:Boolean = false;
            if (this._inuseDic.hasOwnProperty(param1))
            {
                var _loc_6:* = this._inuseDic;
                var _loc_7:* = param1;
                var _loc_8:* = this._inuseDic[param1] - 1;
                _loc_6[_loc_7] = _loc_8;
                if (this._inuseDic[param1] <= 0)
                {
                    delete this._inuseDic[param1];
                    if (this._loadings[param1])
                    {
                        this._loadings[param1] = null;
                        if (this._curFile == param1 && this._isLoading)
                        {
                            this._isLoading = false;
                            this._curFile = 0;
                            _loc_4 = true;
                        }
                        delete this._loadings[param1];
                    }
                    if (this._dataDic[param1])
                    {
                        _loc_5 = this._dataUrls.indexOf(param1);
                        if (_loc_5 > -1)
                        {
                            this._dataUrls.splice(_loc_5, 1);
                            this._dataDic[param1] = null;
                            delete this._dataDic[param1];
                        }
                    }
                    if (param2)
                    {
                        this.destroyRes(param1);
                    }
                    this.checkCache();
                }
            }
            if (_loc_4)
            {
                this.loadNextData();
            }
            return;
        }// end function

        public function unloadById(param1:int) : void
        {
            var _loc_2:String = null;
            if (this._loaderIDs[param1])
            {
                for (_loc_2 in this._loaderIDs[param1])
                {
                    
                    this.unload(int(_loc_2));
                }
                this._loaderIDs[param1] = null;
                delete this._loaderIDs[param1];
            }
            return;
        }// end function

        public function destroy() : void
        {
            return;
        }// end function

        public static function get instance() : SWFActionLoader2
        {
            if (_instance == null)
            {
                _instance = new SWFActionLoader2;
            }
            return _instance;
        }// end function

    }
}
